﻿using Admin.NET.Application.Entity;
using Admin.NET.Application.Service.WcsTask;
using Furion.FriendlyException;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Furion.Logging;
using Admin.NET.Application.Service.WcsService;
using Admin.NET.Application.Service.Tray.Dto;
using OfficeOpenXml.FormulaParsing.Utilities;
using Aop.Api.Domain;
using Org.BouncyCastle.Ocsp;
using StackExchange.Profiling.Internal;
using DocumentFormat.OpenXml.Bibliography;
using Admin.NET.Application.Service.OrderInfo;
using AngleSharp.Dom;
using System.Data;
using Newtonsoft.Json;
using WCS.Application.Service.Inventory.DTO;

namespace Admin.NET.Application.Service.WcsTask;
/// <summary>
/// wcs服务
/// </summary>
[ApiDescriptionSettings(groups: ApplicationConst.GroupName, Order = 14)]

public class WcsTaskService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<WCSTaskManagementEntity> _wcsTaskEntity;
    private readonly UserManager _userinfo;
    private readonly OrderInfoService _orderInfoService;

    public WcsTaskService(SqlSugarRepository<WCSTaskManagementEntity> wcsTaskEntity, UserManager userinfo, OrderInfoService orderInfoService)
    {
        _userinfo = userinfo;
        _wcsTaskEntity = wcsTaskEntity;
        _orderInfoService=orderInfoService;
    }

    /// <summary>
    /// 获取WCS任务信息 🔖
    /// </summary>
    /// <param name="taskInput"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetWcsTaskPageList"), HttpPost]
    public async Task<SqlSugarPagedList<WCSTaskManagementEntity>> GetWcsTaskPageList(WcsTaskDto taskInput)
    {
        // status用枚举判断了
        var list = await _wcsTaskEntity.Context.CopyNew().Queryable<WCSTaskManagementEntity>()
                .WhereIF(!string.IsNullOrWhiteSpace(taskInput.TaskNumber), u => u.TaskNumber.ToLower().Contains(taskInput.TaskNumber.ToLower().Trim()))
                .WhereIF(!string.IsNullOrWhiteSpace(taskInput.Status.ToString()), u => u.Status.Equals(taskInput.Status))
                .WhereIF(!string.IsNullOrWhiteSpace(taskInput.Type.ToString()), u => u.Type.Equals(taskInput.Type))
                .WhereIF(!string.IsNullOrWhiteSpace(taskInput.MaterialCode), u => u.MaterialCode.Contains(taskInput.MaterialCode))
                .OrderBy(u => u.SortId, SqlSugar.OrderByType.Asc) // 按SortId升序排序
                .OrderBy(u => u.CreateTime, SqlSugar.OrderByType.Desc) // 再按CreateTime降序排序
                .ToPagedListAsync(taskInput.Page, taskInput.PageSize);
        return list;
    }

    /// <summary>
    /// 获取订单信息 🔖
    /// </summary>
    /// <param name="taskInput"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetWcsTaskList"), HttpPost]
    public async Task<List<WCSTaskManagementEntity>> GetWcsTaskList(WcsTaskDto taskInput)
    {
        Expression<Func<WCSTaskManagementEntity, bool>> expression = whereExp =>
                 (taskInput.TaskNumber.GetIsEmptyOrNull() || whereExp.TaskNumber.Contains((taskInput.TaskNumber.Trim())))
                 && (taskInput.Status.GetIsEmptyOrNull() || whereExp.Status.Equals(taskInput.Status))
                 && (taskInput.Type.GetIsEmptyOrNull() || whereExp.Type.Equals(taskInput.Type))
                 && (taskInput.MaterialCode.GetIsEmptyOrNull() || whereExp.MaterialCode.Equals(taskInput.MaterialCode));

        var list = await _wcsTaskEntity.Context.CopyNew().Queryable<WCSTaskManagementEntity>().WhereIF(expression != null, expression).OrderBuilder(taskInput).ToListAsync();
        return list;
    }

    /// <summary>
    /// 添加WCS任务
    /// </summary>
    /// <param name="Input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "InsertWcsTask"), HttpPost]

    public async Task<string> InsertWcsTask(AddWcsTaskInput Input)
    {
        #region 唯一索引
        Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                    whereExp.Id.Equals(Input.Id) && whereExp.TaskNumber.Equals(Input.TaskNumber);
        #endregion
        var data = await _wcsTaskEntity.GetFirstAsync(whereExpression);
        if (data != null)
        {
            throw Oops.Oh(10001, "该记录已存在");
        }
        Input.CreateTime = DateTime.Now;
        Input.CreateUserId = _userinfo.UserId;
        Input.CreateUserName = _userinfo.RealName;

        var entity = Input.Adapt<WCSTaskManagementEntity>();

        // 注册雪花Id
        var snowIdOpt = App.GetConfig<SnowIdOptions>("SnowId", true);
        YitIdHelper.SetIdGenerator(snowIdOpt);
        //entity.TaskNumber = await _orderInfoService.GenerateOrderIdAsync();
        Random random = new Random();
        entity.TaskNumber = DateTime.Now.ToString("yyyyMMddHHmmss_") + random.Next(1000,9999);


        entity.TaskNumber.ToLower();
        await _wcsTaskEntity.AsInsertable(entity).ExecuteCommandAsync();
        return entity.TaskNumber;
    }

    /// <summary>
    /// 修改WCS任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "UpdateWcsTask"), HttpPost]

    public async Task<int> UpdateWcsTask(UpdateWcsTaskInput input)
    {
        #region 唯一索引
        Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                    whereExp.TaskNumber.Equals(input.TaskNumber);
        #endregion

        var task = await _wcsTaskEntity.GetFirstAsync(whereExpression);

        try
        {
            if (task != null)
            {
                //记得状态更改调节
                task.Status = input.Status;
                if (task.Status == TaskStatusEnmu.Cancelled)
                {
                    SerilogHelper.WriteLog("UpdateWcsTask失败 任务当前状态是" + task.Status + "");
                    throw Oops.Oh("当前任务状态不可修改");
                }
                else
                {
                    // 对实体进行赋值
                    task.UpdateUserId = _userinfo.UserId;
                    task.UpdateTime = DateTime.Now;
                    task.UpdateUserName = _userinfo.RealName;

                    task.Id = input.Id;
                    task.SN = input.SN;
                    task.Status = input.Status;
                    task.Type = input.Type;
                    task.Channel = input.Channel;
                    task.TrayCode = input.TrayCode;
                    task.HoistOpening = input.HoistOpening;
                    task.ResPonse = input.ResPonse;
                    task.FinishDate = input.FinishDate;
                    task.DownDate = input.DownDate;
                }
            }
            else
            {
                Log.Information("UpdateWcsTask失败 记录不存在");
                throw Oops.Oh("修改WCS任务出现错误：" + ErrorCodeEnum.D1002);
            }
        }
        catch (Exception error)
        {
            SerilogHelper.WriteLog("UpdateWcsTask失败" + error.Message);
            throw Oops.Oh("修改WCS任务出现错误：" + error.Message + "");
        }
        // api已转为entity
        var updateEntity = task.Adapt<WCSTaskManagementEntity>();
        return await _wcsTaskEntity.AsUpdateable(updateEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
        throw Oops.Oh($"重新启动任务{input.TaskNumber}");

    }






    /// <summary>
    /// 更新任务状态为启动未开始
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "UpdateWcsTaskStatusStart"), HttpPost]
    [DisplayName("修改任务状态")]
    public async Task<int> UpdateWcsTaskStatus(List<DeleteWcsInput> input)
    {
        var n = 0;
        foreach (var item in input)
        {
            #region "校验唯一索引"
            Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                        whereExp.Id.Equals(item.Id);
            #endregion    
            var entity = await _wcsTaskEntity.GetFirstAsync(whereExpression) ?? throw Oops.Oh(ErrorCodeEnum.D1002);

            if (entity != null)
            {
                entity.UpdateUserId = _userinfo.UserId;
                entity.UpdateTime = DateTime.Now;
                entity.UpdateUserName = _userinfo.RealName;
                entity.Status = TaskStatusEnmu.NoStarte;
            }
            var updateEntity = entity.Adapt<WCSTaskManagementEntity>();

            n = await _wcsTaskEntity.AsUpdateable(updateEntity).ExecuteCommandAsync();
        }
        return n;
    }
    /// <summary>
    /// 更新任务状态为启动未开始
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "UpdateWcsTaskStatusCancel"), HttpPost]
    [DisplayName("修改任务状态取消")]
    public async Task<int> UpdateWcsTaskStatusCancel(List<DeleteWcsInput> input)
    {
        var n = 0;
        foreach (var item in input)
        {
            #region "校验唯一索引"
            Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                        whereExp.Id.Equals(item.Id);
            #endregion    
            var entity = await _wcsTaskEntity.GetFirstAsync(whereExpression) ?? throw Oops.Oh(ErrorCodeEnum.D1002);

            if (entity != null)
            {
                entity.UpdateUserId = _userinfo.UserId;
                entity.UpdateTime = DateTime.Now;
                entity.UpdateUserName = _userinfo.RealName;
                entity.Status = TaskStatusEnmu.Cancelled;
            }
            var updateEntity = entity.Adapt<WCSTaskManagementEntity>();

            n = await _wcsTaskEntity.AsUpdateable(updateEntity).ExecuteCommandAsync();
        }
        return n;
    }
    /// <summary>
    /// 下发优先级最高的
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "WcstaskEmergency"), HttpPost]
    [DisplayName("修改库存管理 解冻冻结")]
    public async Task<int> UpdateInventoryStatus(List<DeleteWcsInput> input)
    {
        var n = 0;
        foreach (var item in input)
        {
            #region "校验唯一索引"
            Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                        whereExp.Id.Equals(item.Id);
            #endregion    
            var entity = await _wcsTaskEntity.GetFirstAsync(whereExpression) ?? throw Oops.Oh(ErrorCodeEnum.D1002);

            var list = await GetWcsTaskList(new WcsTaskDto { });
            //查询出小于=2 就是进行中和未开始的任务
            list.Where(c => c.Status <= TaskStatusEnmu.Underay).OrderByDescending(c => c.SortId).FirstOrDefault();
            InsertTaskAtFront(list, entity);
            //重新入库
            n = await _wcsTaskEntity.AsUpdateable(entity).ExecuteCommandAsync();
        }
        return n;
    }

    public void InsertTaskAtFront(List<WCSTaskManagementEntity> tasks, WCSTaskManagementEntity newTask)
    {
        if (!tasks.Any())
        {
            newTask.SortId = 0;
        }
        else
        {
            // 找到当前最小的SortId，新任务的SortId为其+1  -会负数
            int minSortId = tasks.Max(t => t.SortId);
            newTask.SortId = minSortId + 1;
        }

        tasks.Add(newTask);

        tasks.Sort((a, b) => a.SortId.CompareTo(b.SortId));

        // 重新分配 SortId，从 0 开始
        for (int i = 0; i < tasks.Count; i++)
        {
            tasks[i].SortId = i;
        }
    }
    /// <summary>  
    /// 返回当前任务序号最大  
    /// </summary>  
    /// <returns></returns>  
    [ApiDescriptionSettings(Name = "GetMaxnumberWcs"), HttpPost]
    public async Task<string> GetMaxnumberWcs()
    {
        var maxNumber = await _wcsTaskEntity.AsQueryable().MaxAsync(c => c.TaskNumber);
        if (maxNumber is null)
            return "1";
        // 提取数字部分并加1  
        var numberPart = new string(maxNumber.Where(char.IsDigit).ToArray());
        if (int.TryParse(numberPart, out int numericValue))
        {
            numericValue += 1;
            return maxNumber.Replace(numberPart, numericValue.ToString().PadLeft(numberPart.Length, '0'));
        }
        SerilogHelper.WriteLog("任务号中的数字部分" + maxNumber);

        throw Oops.Oh("无法解析任务号中的数字部分");
    }
    /// <summary>  
    /// 返回当前任务下发序号最大
    /// </summary>  
    /// <returns></returns>  
    [ApiDescriptionSettings(Name = "GetSortIdWcs"), HttpPost]
    public async Task<int> GetSortIdWcs()
    {
        var maxNumber = await _wcsTaskEntity.AsQueryable().MaxAsync(c => c.SortId);

        // 提取数字部分并加1  
        SerilogHelper.WriteLog("当前下发任务排序id最大值" + maxNumber);
        return maxNumber += 1;


    }


    /// <summary>
    /// 删除wcs任务🔖
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "DeleteWcsTask"), HttpPost]
    [DisplayName("删除订单")]
    public async Task DeleteWcsTask(DeleteWcsInput input)
    {
        //var regionTreeList = await _sysRegionRep.AsQueryable().ToChildListAsync(u => u.Pid, input.Id, true);
        //var regionIdList = regionTreeList.Select(u => u.Id).ToList();
        //await _sysRegionRep.DeleteAsync(u => regionIdList.Contains(u.Id));
        Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                       whereExp.Id.Equals(input.Id);
        var entity = await _wcsTaskEntity.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        if (entity.Status == TaskStatusEnmu.Underay)
        {
            throw Oops.Oh("wcs任务在使用中，正在使用对");
        }
        else
        {
            await _wcsTaskEntity.DeleteAsync(entity); // 假删除
            //await _rep.DeleteAsync(entity); // 真删除
        }
    }
    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="inputList"></param>
    /// <returns></returns>
    [UnitOfWork]
    [ApiDescriptionSettings(Name = "BatchDeleteWcsTask"), HttpDelete]
    [DisplayName("批量删除")]
    public virtual async Task<int> BatchDeleteWcsTask(List<DeleteWcsInput> inputList)
    {
        #region "校验"
        foreach (var input in inputList)
        {
            Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                        whereExp.Id.Equals(input.Id)
                   ;
            var data = await _wcsTaskEntity.GetFirstAsync(whereExpression);
            if (data == null)
            {
                throw Oops.Oh("该记录不存在");
            }

            // *****校验是否有其他表使用该记录*****
        }
        #endregion

        var deleteEntity = inputList.Adapt<List<WCSTaskManagementEntity>>();
        return await _wcsTaskEntity.AsDeleteable()
            .Where(deleteEntity)
            .ExecuteCommandAsync();
    }
    /// <summary>
    /// 下载模版
    /// </summary>
    /// <returns></returns>
    [UnitOfWork]
    [DisplayName("下载模版")]
    public virtual async Task<IActionResult> DownloadWcsTask()
    {
        #region "校验"
        string fileName = "WcsTaskTemplate.xlsx";
        string filePath = $"{AppDomain.CurrentDomain.BaseDirectory}/Template/{fileName}";
        if (!File.Exists(filePath))
        {
            throw Oops.Oh(10002, "找不到该模板：" + filePath);
        }
        #endregion

        var path = Path.Combine(filePath);
        return new FileStreamResult(new FileStream(path, FileMode.Open), System.Net.Mime.MediaTypeNames.Application.Octet)
        {
            FileDownloadName = fileName
        };
    }

    /// <summary>
    /// 导出WCS任务
    /// </summary>·
    [UnitOfWork]
    [DisplayName("导出wcs任务")]
    [ApiDescriptionSettings(Name = "WcsTaskExport"), HttpPost]
    public virtual async Task<IActionResult> WcsTaskExport(ExportWcsInput input)
    {
        Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                   (input.TaskNumber.GetIsEmptyOrNull() || whereExp.TaskNumber.Contains(input.TaskNumber.Trim()))
                   && (input.Status.GetIsEmptyOrNull() || whereExp.Status.Equals(input.Status))
                   && (input.Type.GetIsEmptyOrNull() || whereExp.Type.Equals(input.Type));



        var list = await _wcsTaskEntity.AsQueryable()
           .WhereIF(whereExpression != null, whereExpression).OrderBuilder(input)
           .ToListAsync();
        string path = AppDomain.CurrentDomain.BaseDirectory + "Export";
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        IExcelExporter excelExporter = new ExcelExporter();



        var res = await excelExporter.ExportAsByteArray(list);
        return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = $"WcsTaskExport_{DateTime.Now.ToString("yyyyMMddHHmmss")}_{new Random().Next(10000000, 99999999)}.xlsx" };
    }



    /// <summary>
    /// 暂存出库导入
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [UnitOfWork]
    [DisplayName("暂存出库导入")]
    [ApiDescriptionSettings(Name = "TemporaryWcs "), HttpPost]
    public virtual async Task<List<TemporaryDto>> TemporaryWcsimport([Required] IFormFile file)
    {

        if (file != null)
        {
            var fileDir = AppDomain.CurrentDomain.BaseDirectory + @"ImportFile";
            if (!Directory.Exists(fileDir))

            {
                Directory.CreateDirectory(fileDir);
            }
            //文件名称
            string fileName = file.FileName;
            //文件类型
            string fileType = file.FileName.Substring(fileName.LastIndexOf("."));
            //上传的文件的路径
            string filePath = fileDir + $@"/{fileName}";
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                file.CopyTo(fs);
            }

            if (fileType == ".xlsx" || fileType == ".xls")
            {
                ExcelHelper eh = new ExcelHelper(filePath);
                DataTable dt = eh.ExcelToDataTable("", true);
                eh.Dispose();
                if (dt == null || dt.Rows.Count == 0)
                {
                    throw Oops.Oh("文件为空！");
                }

                #region "校验模板字段"
                if (!dt.Columns.Contains("序号") || !dt.Columns.Contains("出口编码") || !dt.Columns.Contains("托盘码"))
                {
                    throw Oops.Oh("文件模板错误！请重新下载模板");
                }
                var orderid = string.Empty;
                //if (dt.Columns.Contains("任务号"))
                //{

                //    //不存在订单编号自己生成
                //    orderid = await _orderInservice.GenerateOrderIdAsync();
                //}
                orderid = await _orderInfoService.GenerateOrderIdAsync();
                #endregion

                List<TemporaryDto> listLoad = new List<TemporaryDto>();
                int i = 0;
                foreach (DataRow row in dt.Rows)
                {
                    i++;
                    //校验关联信息是否正确仓库代码
                    //if (!string.IsNullOrEmpty(row["任务号"].GetCString()))
                    //{
                    //    orderid = row["任务号"].GetCString();
                    //}
                    orderid = await _orderInfoService.GenerateOrderIdAsync();

                    TemporaryDto orderInfoEntity = new TemporaryDto
                    {
                        TaskNumber = orderid,
                        SortId = row["序号"].GetCInt(),
                        HoistOpening = row["出口编码"].GetCString(),
                        TrayCode = row["托盘码"].GetCString(),
                        Status = TaskStatusEnmu.NoStarte,
                        Type = TaskTypeEnum.Outbound
                    };
                    #region "校验必填项"

                    #endregion
                    //用唯一索引查询非重复 
                    Expression<Func<WCSTaskManagementEntity, bool>> whereExpression = whereExp =>
                        whereExp.TaskNumber.Equals(orderInfoEntity.TaskNumber);
                    var data = await _wcsTaskEntity.GetFirstAsync(whereExpression);
                    if (data == null)
                    {
                        #region "自定义校验"

                        orderInfoEntity.CreateUserId = _userinfo.UserId;
                        orderInfoEntity.CreateTime = DateTime.Now;
                        orderInfoEntity.CreateOrgId = _userinfo.OrgId;
                        orderInfoEntity.CreateUserId = _userinfo.UserId;
                        orderInfoEntity.CreateUserName = _userinfo.RealName;

                        data = _wcsTaskEntity.Adapt(orderInfoEntity);
                        #endregion

                        var rtAdd = await _wcsTaskEntity.AsInsertable(data).ExecuteCommandAsync();
                        if (rtAdd != 1)
                        {
                            orderInfoEntity.ResultCode = 10004;
                            orderInfoEntity.Message = "插入失败";
                        }
                    }
                    else
                    {
                        #region "自定义校验"  

                        data.UpdateUserId = _userinfo.UserId;
                        data.UpdateTime = DateTime.Now;
                        data.UpdateUserName = _userinfo.RealName;
                        data.TrayCode = orderInfoEntity.TrayCode;
                        data.MaterialCode = orderInfoEntity.MaterialCode;
                        data.HoistOpening = orderInfoEntity.HoistOpening;
                        // 使用 Mapster 的 Adapt 方法将 orderInfoEntity 的值替换到 data 中  
                        #endregion
                        //不能用Adapt替换因为importPosition中没主键

                        var order = data.Adapt(orderInfoEntity);
                        var rtUpdate = await _wcsTaskEntity.AsUpdateable(order).ExecuteCommandAsync();
                        if (rtUpdate != 1)
                        {
                            orderInfoEntity.ResultCode = 10004;
                            orderInfoEntity.Message = "更新失败";
                        }
                    }

                    if (orderInfoEntity.ResultCode != 200)
                        listLoad.Add(orderInfoEntity);
                    SerilogHelper.WriteLog("导入数据" + JsonConvert.SerializeObject(orderInfoEntity));

                }

                // 返回导入失败数据
                if (listLoad.Count > 0)
                {
                    return listLoad;
                }
            }
            else
            {
                throw Oops.Oh(10002, "文件内容为空！");
            }
        }
        else
        {
            throw Oops.Oh(10002, "请选择文件！");
        }
        return null;
    }
}

